import { getItem, removeItem, setItem } from '@hs-admin/utils'

const LOCAL_SHOPPING = 'localShopping'
const MODIFIED_SHOPPING = 'modifiedShopping'
const TEMP_SHOPPING_ITEM = 'tempShoppingItem'

const handleLocalData =
  (localStorageKey: string) =>
  (itemId?: string | 'common', property?: string | Record<string, any>, overwrite = false) => {
    let shoppingData = getItem(localStorageKey)

    if (!itemId) {
      if (!shoppingData || JSON.stringify(shoppingData) === '{}') {
        throw '本地数据为空！'
      } else {
        let finalData: Record<string, any> = {}
        const commonData = shoppingData['common']
        if (commonData) {
          Object.keys(shoppingData)
            .filter((key) => key !== 'common')
            .forEach((key) => {
              finalData[key] = shoppingData[key]
            })
        } else {
          finalData = shoppingData
        }
        return finalData
      }
    }
    if (!shoppingData) shoppingData = {}
    setItem(localStorageKey, shoppingData)

    if (property) {
      if (typeof property === 'string') {
        if (overwrite) {
          Reflect.deleteProperty(shoppingData, itemId)
          setItem(localStorageKey, shoppingData)
          return
        } else {
          return shoppingData[itemId]?.[property]
        }
      } else {
        try {
          shoppingData[itemId] = shoppingData[itemId] ?? {}
          if (overwrite) {
            shoppingData[itemId] = property
          } else {
            shoppingData[itemId] = Object.assign(shoppingData[itemId], property)
          }
          setItem(localStorageKey, shoppingData)
        } catch (e) {
          console.error('出错了', e)
          throw '出错了，错误详情看控制台'
        }
      }
    } else {
      return shoppingData[itemId]
    }
  }

/**
 * localShoppingData用法：
 *
 * -不传参数，返回所有购物车数据（注意，无数据时会报错；且通用数据‘common’已做处理，无需再次处理）
 *
 * -传itemId,返回该条数据的全部属性（注意：通用数据的itemId请使用‘common’）
 *
 * -传itemId与property，且property为string，返回该条数据的[property]
 *
 * -传itemId与property，且property为string，且传了overwrite为true，清空该条数据的该property
 *
 * -传itemId与property，且property为一个对象，该条数据的旧值与新值property合并
 *
 * -传itemId与property，且property为一个对象，且传了overwrite为true,该条数据抛弃旧值，使用新值覆盖
 * */
export const localShoppingData = handleLocalData(LOCAL_SHOPPING)

export const clearLocalShopping = (id?: string) => {
  if (id) {
    const theData = getItem(LOCAL_SHOPPING)
    if (theData?.[id]) {
      Reflect.deleteProperty(theData, id)
      setItem(LOCAL_SHOPPING, theData)
    }
  } else {
    removeItem(LOCAL_SHOPPING)
  }
}

/**
 * ModifiedSeverShoppingData用法：
 *
 * 同localShoppingData*/
export const ModifiedSeverShoppingData = handleLocalData(MODIFIED_SHOPPING)

export const clearShoppingData = () => removeItem(LOCAL_SHOPPING)

export const clearModifiedData = () => removeItem(MODIFIED_SHOPPING)

export const tempData = (property?: string | Record<string, any>, overwrite = false) => {
  let temp = getItem(TEMP_SHOPPING_ITEM)
  if (!property) {
    return temp
  } else {
    if (typeof property === 'string') {
      return temp?.[property]
    } else if (typeof property === 'object') {
      if (!temp) temp = {}
      if (overwrite) temp = property
      else Object.assign(temp, property)
      setItem(TEMP_SHOPPING_ITEM, temp)
    } else {
      throw `错误的用法，${property}`
    }
  }
}

export type StorageFunctionType = ReturnType<typeof handleLocalData>
export type TempStorageFunctionType = typeof tempData
